package com.liziyi0914.morearmor;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ClassUtil;
import com.liziyi0914.morearmor.armor.BaseArmor;
import com.liziyi0914.morearmor.armormaterial.BaseArmorMaterial;
import com.liziyi0914.morearmor.event.EventManager;
import com.liziyi0914.morearmor.event.IListener;
import com.liziyi0914.morearmor.event.entity.WorldTickEvent;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.minecraft.block.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.*;
import net.minecraft.util.Identifier;
import net.minecraft.util.crash.CrashReport;
import net.minecraft.util.registry.Registry;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class MoreArmorMod implements ModInitializer {

    public static final String MODID = "more_armor";

    public static final ItemGroup GROUP = FabricItemGroupBuilder.build(new Identifier(MODID, "tab"), () -> new ItemStack(Blocks.CHEST));

    @Override
    public void onInitialize() {
        loadFabricListener();
        loadEffect();
        Field[] fields = Items.class.getFields();
        for (Field field : fields) {
            try {
                Object obj = field.get(null);
                if (obj instanceof Item item) {
                    if (isInvalid(item)) continue;
                    String name = Registry.ITEM.getId(item).getPath();
                    ArmorMaterial material = new BaseArmorMaterial(name);
                    Registry.register(Registry.ITEM, new Identifier(MODID, name + "_helmet"), new BaseArmor(item, material, EquipmentSlot.HEAD));
                    Registry.register(Registry.ITEM, new Identifier(MODID, name + "_chestplate"), new BaseArmor(item, material, EquipmentSlot.CHEST));
                    Registry.register(Registry.ITEM, new Identifier(MODID, name + "_leggings"), new BaseArmor(item, material, EquipmentSlot.LEGS));
                    Registry.register(Registry.ITEM, new Identifier(MODID, name + "_boots"), new BaseArmor(item, material, EquipmentSlot.FEET));
                }
            } catch (IllegalAccessException ignored) {
            }
        }
//        saveRegisterItem();
    }

    public void saveRegisterItem() {
        final File file = new File("items.txt");
        FileUtil.del(file);
        FileUtil.appendUtf8Lines(Registry.ITEM.stream().filter(item -> item instanceof BaseArmor)
                .map(item -> Registry.ITEM.getId(item).getPath()).toList(), file);
        final File reg = new File("register.txt");
        FileUtil.del(reg);
        FileUtil.appendUtf8Lines(Registry.ITEM.stream().filter(item -> item instanceof BaseArmor)
                .map(item -> Registry.ITEM.getId(((BaseArmor) item).getItem()).getPath()).distinct().toList(), reg);

    }

    public static boolean isInvalid(Item item) {
        return
                item == null
                        || item == Items.DIAMOND
                        || item == Items.IRON_INGOT
                        || item == Items.GOLD_INGOT
                        || item == Items.NETHERITE_INGOT
                        || item == Items.ANCIENT_DEBRIS
                        || Registry.ITEM.getId(item).getPath().contains("brick")
                        || item instanceof ArmorItem
                        || item instanceof ArrowItem
                        || item instanceof ToolItem
                        || item instanceof BannerItem
                        || item instanceof BoatItem
                        || item instanceof SpawnEggItem
                        || item instanceof MusicDiscItem
                        || item instanceof DebugStickItem
                        || item instanceof SkullItem
                        || Block.getBlockFromItem(item) instanceof DoorBlock
                        || Block.getBlockFromItem(item) instanceof SkullBlock
                        || Block.getBlockFromItem(item) instanceof SpawnerBlock
                        || Block.getBlockFromItem(item) instanceof AnvilBlock
                        || Block.getBlockFromItem(item) instanceof StairsBlock
                        || Block.getBlockFromItem(item) instanceof WallMountedBlock
                        || Block.getBlockFromItem(item) instanceof OreBlock
                        || Block.getBlockFromItem(item) instanceof AbstractButtonBlock
                        || Block.getBlockFromItem(item) instanceof RailBlock
                        || Block.getBlockFromItem(item) instanceof SignBlock
                        || Block.getBlockFromItem(item) instanceof WallBlock
                        || Block.getBlockFromItem(item) instanceof SlabBlock
                        || Block.getBlockFromItem(item) instanceof FlowerBlock
                        || Block.getBlockFromItem(item) instanceof AbstractPressurePlateBlock
                        || new ItemStack(item).isEmpty()
                ;
    }

    public void loadEffect() {
        EventManager.registerListener(new StatusEffectManager());

        ClassUtil.scanPackage("com.liziyi0914.morearmor.effect", cls -> cls.getName().matches("^((?!Abstract).)*Effect$")).forEach(cls -> {
            try {
                EventManager.registerListener((IListener) cls.getDeclaredConstructor().newInstance());
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                MinecraftClient.printCrashReport(CrashReport.create(e, String.format("error to create effect class %s", cls)));
            }
        });
    }

    public void loadFabricListener() {
        ClientTickEvents.START_WORLD_TICK.register(world -> EventManager.call(new WorldTickEvent(world)));
    }
}
